<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

</body>
<script>
    //1、变量作用域
    //全局变量
    // 局部变量
    // 函数内部可以直接读取全局变量，函数外部无法读取函数内部的局部变量-->
    //2、从函数外部读取局部变量
    //  解决方法：在函数内部在定义一个函数
    function f1() {
        var n = 1;
        function f2() {
            alert(n);
        }
    }
    // 1、闭包的概念
    //闭包就是能够读取其他函数内部变量的函数

    //暂时性死区
    //只要块级作用域内存在let命令，
    // 它所声明的变量就“绑定”这个区域，不再受外部的影响。
    //在代码块内，使用let、const命令声明变量之前，该变量都是不可用的。这在语法上，称为“暂时性死区”
    if (true) {
        shuzi= 'abc';
        let tmp;
    }

    //变量提升
    //少用var容易出事，除非特殊逼不得已
    // var 的情况.声明提升赋值不会提升
    //用var定义了变量之后，会将定义行为提升至顶部，然后将赋值行为保留在远处，这就是所谓的变量提升。
    console.log(foo); // 输出undefined
    var foo = 2;
    //相当于
    // var foo;  //声明且初始化为undefined
    // console.log(foo);
    // foo=2;
    // // let 的情况
    // console.log(bar); // 报错
    // let bar = 2;
    // //let不会变量提升，多用这个安全第一


    //函数声明的变量提升
    //不管什么时候优先提升函数
    //    fun(); // 1
    //    let fun;
    //    function fun() {
    //        console.log( 1 );
    //    }
    //    fun = function() {
    //        console.log( 2 );
    //    };
    // 会输出 1 而不是 2 ！这个代码片段会被引擎理解为如下形式：
    function fun() {
        console.log( 1 );
    }
    fun(); // 1
    fun = function() {
        console.log( 2 );}
</script>
</html>